#ifndef LIBCELL_POINTS_CLOUD_ALGORITHM_H_
#define LIBCELL_POINTS_CLOUD_ALGORITHM_H_

#ifndef SIGN
#define SIGN(x) ((x>0)?1:((x<0)?-1:0))
#endif SIGN

#include<Mesh/_Func_.h>
#include<tool/libcell_tools_algorithm.h>
#include<tool/libcell_tools_octree.h>
#include<tool/libcell_tools_kd_node.h>
#include<Math/LB_Math.h>
// #include<Mesh/libcell_iterator.h>
// #include<tool/libcell_kd_node_iterator.h>

#ifdef __cplusplus
extern "C" {
#endif
// adjacent要修改
//
typedef struct Points_Open_Set{
    //n :: set of vertices
    //adjacent:: bigcap of open sets 
    Node* n,*adjacent;
    template_v* v;
    double * normal;
}Points_Open_Set;

static inline void points_open_set_init(Points_Open_Set* pos)
{
    pos->n=NULL;pos->v=NULL;pos->adjacent=NULL;
    pos->normal=NULL;   
}

static inline void points_open_set_free(Points_Open_Set* pos)
{
    if(pos==NULL)
    {
        return ;
    }
    free_node(pos->adjacent);
    free_node(pos->n);
    if(pos->normal!=NULL)
    {
        free(pos->normal);
    }
    free(pos);
}
Node* compute_points_open_sets(Node* n,Int_RB_Tree* tree,double r,KD_Node* kdtree);

double*compute_pca_result_using_clapack(Node* n);

void points_cloud_compute_normal_using_clapack(Node* n,KD_Node*kdtree,int num);

double**compute_pca_result(Node* n);


void points_cloud_compute_normal(Node* n,KD_Node*kdtree,int num);
void points_cloud_compute_normalr(Node* n,KD_Node*kdtree,double r);



void adjust_normal_of_node_vertices(Node*n,double r,KD_Node* kdtree);




int is_boundary_vertex_in_points_cloud(KD_Node*tree,template_v* v,double r);

Node* downsampling_through_oc_tree(Node* vertices,int depth);


Node* downsampling_through_size(Node* vertices,double len );
Node* downsampling_through_size1(Node* vertices,double len );

Node* get_cluster_points_from_mesh1(Mesh * m,double r);


//求 data1 到data2的最优变换
double** compute_optimal_rigid_body_transformation(double** data1,double** data2,int len);


#ifdef __cplusplus
}
#endif

#endif
